#include"Board.h"
#include<QPainter>
#include<QMouseEvent>
//画棋盘
Board::Board(QWidget *parent):
    QWidget{parent}
{
    for(int i=0;i<32;++i){
        _s[i].init(i);
    }
    _selectid=-1;
    _bRedTurn=true;
}
void Board::paintEvent(QPaintEvent*){

    QPainter painter(this);
    int d=40;
    _r=d/2;

    //横线
    for(int i=1;i<=10;++i){
        painter.drawLine(QPoint(d,i*d),QPoint(9*d,i*d));
    }

    //竖线
    for(int i=1;i<=9;++i){
        if(i==1||i==9){
            painter.drawLine(QPoint(i*d,d),QPoint(i*d,10*d));
        }
        else{
            painter.drawLine(QPoint(i*d,d),QPoint(i*d,5*d));
            painter.drawLine(QPoint(i*d,6*d),QPoint(i*d,10*d));
        }
    }

    //中宫
    painter.drawLine(QPoint(4*d,d),QPoint(6*d,3*d));
    painter.drawLine(QPoint(6*d,d),QPoint(4*d,3*d));
    painter.drawLine(QPoint(4*d,8*d),QPoint(6*d,10*d));
    painter.drawLine(QPoint(6*d,8*d),QPoint(4*d,10*d));

    //棋子
    for(int i=0;i<32;++i){
        drawStone(painter,i);
    }
}

QPoint Board::center(int row,int col){
    QPoint ret;
    ret.rx() = (col+1)*_r*2;
    ret.ry() = (row+1)*_r*2;
    return ret;
}

QPoint Board::center(int id){
    return center(_s[id]._row,_s[id]._col);
}

void::Board::drawStone(QPainter& painter, int id){
    if(_s[id]._dead==true){
        return;
    }
    QPoint c=center(id);
    QRect rect=QRect(c.x()-_r,c.y()-_r,_r*2,_r*2);

    if(id==_selectid){
        painter.setBrush(QBrush(Qt::gray));
    }
    else
        painter.setBrush(QBrush(Qt::yellow));
    painter.setPen(Qt::black);



    painter.drawEllipse(center(id),_r,_r);
    if(_s[id]._red){
        painter.setPen(Qt::red);
        painter.setFont(QFont("system",_r,700));
    }


    painter.drawText(rect,_s[id].getText(),QTextOption(Qt::AlignCenter));
}

//定义一个函数，确定两个棋子之间还有多少个棋子
bool Board::isDead(int id)
{
    if(id == -1)return true;
    return _s[id]._dead;
}

int Board::getStoneId(int row,int col){
    for(int i=0; i<32; ++i)
    {
        if(_s[i]._row == row && _s[i]._col == col && !isDead(i))
            return i;
    }
    return -1;

}
int Board::getStoneCountAtLine(int row1,int col1,int row2,int col2){
    int ret=0;
    if(row1!=row2&&col1!=col2){
        return -1;
    }
    if(row1==row2&&col1==col2){
        return -1;
    }
    if(row1==row2){
        int min=col1<col2?col1:col2;
        int max=col1<col2?col2:col1;
        for(int col=min+1;col<max;++col){
            if(getStoneId(row1,col)!=-1){
                ret++;
            }
        }
    }
    else{
        int min=col1<col2?col1:col2;
        int max=col1<col2?col2:col1;
        for(int row=min+1;row<max;++row){
            if(getStoneId(row1,row)!=-1){
                ret++;
            }
        }
    }
    return ret;
}


bool Board::getRowCol(QPoint pt,int& row,int &col){
    for(row=0;row<=9;row++){
        for(col=0;col<=8;col++){
            QPoint c=center(row,col);
            int dx=c.x()-pt.x();
            int dy=c.y()-pt.y();
            int dist=dx*dx+dy*dy;
            if(dist<_r*_r){
                return true;
            }
        }
    }
    return false;
}

bool Board::canMoveJIANG(int moveid,int row,int col,int killid){

    if(_s[moveid]._red){
        if(row>2){
            return false;
        }
    }
    else{
        if(row<7){
            return false;
        }
    }
    if(col<3){
        return false;
    }
    if(col>5){
        return false;
    }

    int dr=_s[moveid]._row-row;
    int dc=_s[moveid]._col-col;
    int d=abs(dr)*abs(dr)+abs(dc)*abs(dc);
    if(d==1){
        return true;
    }

    return false;
}
bool Board::canMoveSHUAI(int moveid,int row,int col,int killid){
    if(_s[moveid]._red){
        if(row>2){
            return false;
        }
    }
    else{
        if(row<7){
            return false;
        }
    }
    if(col<3){
        return false;
    }
    if(col>5){
        return false;
    }

    int dr=_s[moveid]._row-row;
    int dc=_s[moveid]._col-col;
    int d=abs(dr)*abs(dr)+abs(dc)*abs(dc);
    if(d==1){
        return true;
    }

    return false;
}
bool Board::canMoveSHI1(int moveid,int row,int col,int killid){
    if(_s[moveid]._red){
        if(row>2){
            return false;
        }
    }
    else{
        if(row<7){
            return false;
        }
    }
    if(col<3){
        return false;
    }
    if(col>5){
        return false;
    }

    int dr=_s[moveid]._row-row;
    int dc=_s[moveid]._col-col;
    int d=abs(dr)*abs(dr)+abs(dc)*abs(dc);
    if(d==2){
        return true;
    }

    return false;
}
bool Board::canMoveSHI2(int moveid,int row,int col,int killid){
    if(_s[moveid]._red){
        if(row>2){
            return false;
        }
    }
    else{
        if(row<7){
            return false;
        }
    }
    if(col<3){
        return false;
    }
    if(col>5){
        return false;
    }

    int dr=_s[moveid]._row-row;
    int dc=_s[moveid]._col-col;
    int d=abs(dr)*abs(dr)+abs(dc)*abs(dc);
    if(d==2){
        return true;
    }

    return false;
}
bool Board::canMoveXIANG1(int moveid,int row,int col,int killid){
    if(_s[moveid]._red){
        if(row>4){
            return false;
        }
    }
    else{
        if(row<5){
            return false;
        }
    }
    //象走田
    int dr=_s[moveid]._row-row;
    int dc=_s[moveid]._col-col;
    int d=abs(dr)*abs(dr)+abs(dc)*abs(dc);
    if(d==8){
        return true;
    }
    return false;
}
bool Board::canMoveXIANG2(int moveid,int row,int col,int killid){
    if(_s[moveid]._red){
        if(row>4){
            return false;
        }
    }
    else{
        if(row<5){
            return false;
        }
    }
    //象走田
    int dr=_s[moveid]._row-row;
    int dc=_s[moveid]._col-col;
    int d=abs(dr)*abs(dr)+abs(dc)*abs(dc);
    if(d==8){
        return true;
    }
    return false;
}
bool Board::canMoveMA(int moveid,int row,int col,int killid){
    //马走日
    int dr=_s[moveid]._row-row;
    int dc=_s[moveid]._col-col;
    int d=abs(dr)*abs(dr)+abs(dc)*abs(dc);
    if(d==5){
        return true;
    }
    return false;
}
bool Board::canMoveCHE1(int moveid,int row,int col,int killid){
    int row1=_s[moveid]._row;
    int col1=_s[moveid]._col;
    int ret=getStoneCountAtLine(row1,col1,row,col);
    if(ret==0){
        return true;
    }
    return false;
}
bool Board::canMoveCHE2(int moveid,int row,int col,int killid){
    int row1=_s[moveid]._row;
    int col1=_s[moveid]._col;
    int ret=getStoneCountAtLine(row1,col1,row,col);
    if(ret==0){
        return true;
    }
    return false;
}
bool Board::canMovePAO1(int moveid,int row,int col,int killid){
    int row1=_s[moveid]._row;
    int col1=_s[moveid]._col;
    int ret=getStoneCountAtLine(row1,col1,row,col);
    if(ret==0){
        return true;
    }
    return false;
}
bool Board::canMovePAO2(int moveid,int row,int col,int killid){
    int row1=_s[moveid]._row;
    int col1=_s[moveid]._col;
    int ret=getStoneCountAtLine(row1,col1,row,col);
    if(ret==0){
        return true;
    }
    return false;
}
bool Board::canMoveZU(int moveid,int row,int col,int killid){
    int dr=_s[moveid]._row-row;
    int dc=_s[moveid]._col-col;
    if(row>6){
        return false;
    }
    //一去不回还
    if(row<=4){
        if(dr==1||abs(dc)==1){
            return true;
        }
    }
    if(row==4||row==5){
        if(dr==1){
            return true;
        }
    }
    return false;
}
bool Board::canMoveBING(int moveid,int row,int col,int killid){
    int dr=_s[moveid]._row-row;
    int dc=_s[moveid]._col-col;
    if(row<3){
        return false;
    }
    //一去不回还
    if(row>=5){
        if(dr==-1||abs(dc)==1){
            return true;
        }
    }
    if(row==4||row==5){
        if(dr==-1){
            return true;
        }
    }
    return false;
}


bool Board::canMove(int moveid,int row,int col,int killid){
    if(_s[moveid]._red==_s[killid]._red){
        _selectid=killid;
        update();
        return false;
    }

    //棋规

    switch(_s[moveid]._type){
    case Stone::JIANG:
        return canMoveJIANG(moveid,row,col,killid);
        break;
    case Stone::SHUAI:
        return canMoveSHUAI(moveid,row,col,killid);
        break;
    case Stone::SHI1:
        return canMoveSHI1(moveid,row,col,killid);
        break;
    case Stone::SHI2:
        return canMoveSHI2(moveid,row,col,killid);
        break;
    case Stone::XIANG1:
        return canMoveXIANG1(moveid,row,col,killid);
        break;
    case Stone::XIANG2:
        return canMoveXIANG2(moveid,row,col,killid);
        break;
    case Stone::MA:
        return canMoveMA(moveid,row,col,killid);
        break;
    case Stone::CHE1:
        return canMoveCHE1(moveid,row,col,killid);
        break;
    case Stone::CHE2:
        return canMoveCHE2(moveid,row,col,killid);
        break;
    case Stone::PAO1:
        return canMovePAO1(moveid,row,col,killid);
        break;
    case Stone::PAO2:
        return canMovePAO2(moveid,row,col,killid);
        break;
    case Stone::ZU:
        return canMoveZU(moveid,row,col,killid);
        break;
    case Stone::BING:
        return canMoveBING(moveid,row,col,killid);
        break;
    }

    return true;
}

void Board::mouseReleaseEvent(QMouseEvent* ev){
    QPoint pt=ev->pos();

    int row,col;
    bool bRet=getRowCol(pt,row,col);
    if(bRet==false){
        return;
    }
    //选中
    int clickid=-1;
    int i;

        for(i=0;i<32;++i){
            if(_s[i]._row==row&&_s[i]._col==col&&_s[i]._dead==false){
                break;
            }
        }
        if(i<32){
            clickid=i;
        }
    if(_selectid==-1){

        if(clickid!=-1){
            if(_bRedTurn==_s[clickid]._red){
                _selectid=clickid;
                update();
            }
        }
    }
    //轮流走
    else{
        if(canMove(_selectid,row,col,clickid)){
            _s[_selectid]._row=row;
            _s[_selectid]._col=col;
            if(clickid!=-1){
                _s[clickid]._dead=true;
            }
            _selectid=-1;
            _bRedTurn= !_bRedTurn;
            update();
        }
    }
}
